/**
 * Copyright (C), 2015-2020, XXX有限公司
 * FileName: ProcessXZ
 * Author:   ThinkPad
 * Date:     2020/6/24 17:03
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.jt.www.queue.process;

import com.jt.www.enums.issue.InvoiceTypeEnum;
import com.jt.www.enums.issue.IssueEnum;
import com.jt.www.enums.issue.PolicyInterfaceEnum;
import com.jt.www.model.issue.entity.IssuePolicyLogEntity;
import com.jt.www.model.issue.entity.IssueRecordEntity;
import com.jt.www.util.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Random;

/**
 * @author xq.wu
 * @Description 学责险（学生安全责任保险）
 * @create 2020/6/24
 * @since 1.0.0
 */
@Service
public class ProcessXZ extends ElecPolicyProcess implements InitializingBean {

    public static final Logger log = LoggerFactory.getLogger(ProcessXZ.class);

    @Override
    public void afterPropertiesSet() throws Exception {
        IssuePolicyIfCodeFactory.register(PolicyInterfaceEnum.CODE_13.getIfCode(), this);
    }

    @Override
    public Boolean process(Element rootElement, String ifCode) {
        // 解析xml，封装数据
        Element reqPacket = getReqPacket(rootElement);
        Element respPacket = getRespPacket(rootElement);

        String mainTypeStr = "0";
        //String proCode = reqPacket.element("Body").element("Apply").element("PolicyHolder").element("PolicyType").getStringValue();
        String proCode = IssueEnum.getProCodeByIfCode(ifCode);
        String companyCode = reqPacket.element("Head").element("UserId").getStringValue();
        String currentTime = DateUtils.getCurrentTime();
        // 投保单号
        String tbNo = rootElement.element("ApplicationFormCode").getStringValue();
        // 保单号
        String policyNo = rootElement.element("PolicyNo").getStringValue();
        // 入库
        // 入库之前首先判断 是否已经入库  根据投保单号判断
        if (judgingStorage(tbNo)) {
            return true;
        }
        IssueRecordEntity issueRecordEntity = new IssueRecordEntity();
        issueRecordEntity.setApplicationFormCode(tbNo);


        issueRecordEntity.setMainType(mainTypeStr);
        issueRecordEntity.setPolicyNo(policyNo);
        issueRecordEntity.setCompanyCode(companyCode);
        issueRecordEntity.setProCode(proCode);
        issueRecordEntity.setReqPacket(reqPacket.asXML());
        issueRecordEntity.setResPacket(respPacket.asXML());
        issueRecordEntity.setSendStatus("1");
        String status = respPacket.element("Head").element("ResponseCode").getStringValue();
        if ("0".equals(status)) {// 成功
            status = "2";
        } else {
            status = "3";
        }
        // 数据中心返回 的投保单状态
        issueRecordEntity.setStatus(status);

        issueRecordEntity.setCreateTime(currentTime);
        issueRecordEntity.setUpdateTime(currentTime);
        issueRecordEntity.setIfCode(ifCode);
        issueRecordEntityMapper.insert(issueRecordEntity);
        if ("3".equals(status)) {// 成功
            // 出单失败，消息直接消费完成。
            return true;
        }
        // 消费  ： 需要组织报文，去调用接口
        IssuePolicyLogEntity issuePolicyLogEntity = new IssuePolicyLogEntity();
        String consumeStatus = "1";
        issuePolicyLogEntity.setApplicationFormCode(tbNo);
        issuePolicyLogEntity.setPolicyNo(policyNo);
        issuePolicyLogEntity.setType("1");
        issuePolicyLogEntity.setStatus(consumeStatus);
        issuePolicyLogEntity.setCreateTime(currentTime);
        issuePolicyLogEntity.setUpdateTime(currentTime);
        issuePolicyLogEntity.setProCode(proCode);
        // 组装报文
        Document doc = DocumentHelper.createDocument();
        Element info = doc.addElement("Message");
        doc.setRootElement(info);
        Element body = info.addElement("Body");
        Element policies = body.addElement("Policies");
        policies.addElement("ApplicationFormCode").addText(tbNo);
        policies.addElement("PolicyNo").addText(policyNo);
        policies.addElement("CompanyCode").addText(companyCode);
        issuePolicyLogEntity.setParam(info.asXML());
        issuePolicyLogEntity.setMainType(mainTypeStr);
        issuePolicyLogEntity.setTimes(0);
        issuePolicyLogEntity.setIfCode(ifCode);
        issuePolicyLogEntityMapper.insert(issuePolicyLogEntity);
        // 只要消息进入消费记录的库，就认为消费成功，修改消息记录表状态,具体有没有成功 记录在消费记录表，有定时任务。
        issueRecordEntity.setSendStatus("2");
        issueRecordEntityMapper.updateByPrimaryKeySelective(issueRecordEntity);

        Boolean flag = false;
        try {
            // 请求下载保单，成功更新
            log.info(DateUtils.getCurrentTime() + "学责投保单号" + tbNo + "下载保单开始，入参" + info.asXML());
            String seqNo = Long.toString(Math.abs(new Random().nextLong()));
            ResponseEntity<String> responseEntity = null;
            try {
                responseEntity = dexClient.text("edu", "20190515003", "1.0", seqNo, info.asXML());
                String ebody = responseEntity.getBody();
                log.info(DateUtils.getCurrentTime() + "学责投保单号" + tbNo + "下载保单结束，回参" + ebody + "," + responseEntity.getStatusCodeValue());
                doc = DocumentHelper.parseText(ebody);
                Element ebodyElement = doc.getRootElement();
                Element data = ebodyElement.element("data");
                consumeStatus = "2";
                if (data == null) {
                    log.error("学责请求下载电子保单失败");
                    consumeStatus = "3";
                }
                String fileId = data.getStringValue();
                issuePolicyLogEntity.setStatus(consumeStatus);
                // 下载电子保单成功，更新数据库，绑定资源
                log.info("学责 下载消息 fileId ：{}", fileId);
                bindingResources(tbNo, fileId, issuePolicyLogEntity);
            } catch (Exception e) {
                e.printStackTrace();
                issuePolicyLogEntity.setTimes(1);
                issuePolicyLogEntity.setStatus("3");
                issuePolicyLogEntityMapper.updateByPrimaryKeySelective(issuePolicyLogEntity);

            }
            sendEmail(tbNo, "21");
            Map<String, String> invoiceList = getAppcodeInvoiceType(tbNo);
            // 只有山西地区  有发票
            String issuingCompanyId = reqPacket.element("Body").element("Apply").element("IssuingCompanyInfo").element("IssuingCompanyId").getStringValue();
            /*if ("301400".equals(issuingCompanyId)) {*/ // 有发票
            if (invoiceList.get("invoiceType").equals(InvoiceTypeEnum.ELECTRONIC_INVOICE.getType())) {

                log.info(DateUtils.getCurrentTime() + "学责山西地区生成发票开始，，，");
                // 下载电子发票 拼装参数
                IssuePolicyLogEntity t = new IssuePolicyLogEntity();
                consumeStatus = "1";
                t.setApplicationFormCode(tbNo);
                t.setPolicyNo(policyNo);
                t.setType("3");
                t.setStatus(consumeStatus);
                t.setCreateTime(currentTime);
                t.setUpdateTime(currentTime);
                t.setProCode(proCode);
                t.setMainType(mainTypeStr);
                t.setIfCode(ifCode);
                doc = DocumentHelper.createDocument();

                // 组装电子发票的报文
                String serialNo = respPacket.element("Head").element("SeqNo").getStringValue();
                String fee = respPacket.element("Body").element("Apply").element("Fee").getStringValue();
                String taxpayerNo = reqPacket.element("Body").element("Apply").element("PolicyHolder").element("IdenCode").getStringValue();
                info = doc.addElement("Message");
                doc.setRootElement(info);
                Element Head = info.addElement("Head");
                Head.addElement("OrderNo").addText("");
                Element Body = info.addElement("Body");
                Element policyInfo = Body.addElement("PolicyInfo");
                policyInfo.addElement("PRODUCTCODE").addText("152901");
                policyInfo.addElement("SerialNo").addText(serialNo);
                policyInfo.addElement("PolicyNo").addText(policyNo);
                policyInfo.addElement("TaxpayerNo").addText(taxpayerNo);
                //新增购方信息
                String bankAddress = invoiceList.get("bankAddress");
                String mobile = invoiceList.get("mobile");
                String bankName = invoiceList.get("bankName");
                String bankNo = invoiceList.get("bankNo");
                policyInfo.addElement("BANKADDRESS").addText(StringUtils.isEmpty(bankAddress) ? "" : bankAddress);
                policyInfo.addElement("MOBILE").addText(StringUtils.isEmpty(mobile) ? "" : mobile);
                policyInfo.addElement("BANKNAME").addText(StringUtils.isEmpty(bankName) ? "" : bankName);
                policyInfo.addElement("BANKNO").addText(StringUtils.isEmpty(bankNo) ? "" : bankNo);
                policyInfo.addElement("Amount").addText("1");
                policyInfo.addElement("TotalJyje").addText(fee);
                t.setParam(info.asXML());
                t.setTimes(0);
                issuePolicyLogEntity.setIfCode(ifCode);
                // 电子发票的消费记录入库
                issuePolicyLogEntityMapper.insert(t);

                log.info(DateUtils.getCurrentTime() + "学责投保单号" + tbNo + "生成发票开始，入参" + info.asXML());
                // 调接口  生成发票
                seqNo = Long.toString(Math.abs(new Random().nextLong()));
                responseEntity = dexClient.text("edu", "20190515013", "1.0", seqNo, info.asXML());
                consumeStatus = "6";
                String ebody = responseEntity.getBody();
                log.info(DateUtils.getCurrentTime() + "学责投保单号" + tbNo + "生成发票结束，回参" + ebody + "," + responseEntity.getStatusCodeValue());
                doc = DocumentHelper.parseText(ebody);
                Element ebodyElement = doc.getRootElement();
                String code = ebodyElement.element("POLICY").attributeValue("RETURN");

                Element downData = null;
                if ("true".equals(code)) {
                    doc = DocumentHelper.createDocument();
                    info = doc.addElement("Message");
                    doc.setRootElement(info);
                    Body = info.addElement("Body");
                    t.setDownParam(info.asXML());
                    t.setStatus(consumeStatus);
                    // 生成电子发票成功，更新数据库，
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                } else {
                    log.error("请求生成电子保单失败");
                    consumeStatus = "7";
                    t.setStatus(consumeStatus);
                    // 生成电子发票失败，更新数据库，
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    return true;
                }

                log.info(DateUtils.getCurrentTime() + "学责投保单号" + tbNo + "下载发票开始，入参" + info.asXML());
                seqNo = Long.toString(Math.abs(new Random().nextLong()));
                responseEntity = dexClient.text("edu", "20190515013", "1.1", seqNo, info.asXML());
                log.info(DateUtils.getCurrentTime() + "学责投保单号" + tbNo + "下载发票结束，回参" + responseEntity.getBody() + "," + responseEntity.getStatusCodeValue());
                // 请求200，继续执行
                if (responseEntity.getStatusCodeValue() != 200) {
                    log.error("请求下载电子发票失败");
                    t.setStatus("6");
                    t.setTimes(1);
                    issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                } else {
                    ebody = responseEntity.getBody();
                    doc = DocumentHelper.parseText(ebody);
                    ebodyElement = doc.getRootElement();
                    code = ebodyElement.element("code").getStringValue();
                    if ("0000".equals(code)) {
                        String eInvoiceId = ebodyElement.element("data").getStringValue();
                        t.setStatus("2");
                        t.setEInvoiceId(eInvoiceId);
                        bindInvoice(tbNo, eInvoiceId, t);// todo 07-09 15:12
                    } else {
                        t.setStatus("6");
                        t.setTimes(1);
                        issuePolicyLogEntityMapper.updateByPrimaryKeySelective(t);
                    }
                }
            }
            log.info(DateUtils.getCurrentTime() + "学责山西地区生成发票结束，，，");
            /*}else {// 没有发票
                log.info(DateUtils.getCurrentTime() + "学责非山西地区不用生成发票，，，");
            }*/
            return true;
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}